package orbito.physics.motion;

import orbito.entity.Entity;
import orbito.util.Vec2;

public abstract class Actor extends Entity {
	State state;
	double mass, inertia;

	Vec2 accumulatedForce;
	double accumulatedTorque;
	
	public Actor() {
		this(new Vec2(), new Vec2(), 0.0, 0.0, 1.0, 1.0);
	}
	
	public Actor(Vec2 position, Vec2 velocity, double angle, double angularSpeed, double mass, double inertia) {
		state = new State(position, velocity, angle, angularSpeed);
		
		this.mass = mass;
		this.inertia = inertia;
		
		accumulatedForce = new Vec2();
		accumulatedTorque = 0.0;
	}
	
	public Vec2 getAcceleration() {
		return accumulatedForce.div(mass);
	}
	
	public double getAngularAcceleration() {
		return accumulatedTorque / inertia;
	}
	
	public void clearAccumulatedForces() {
		accumulatedForce.zeroize();
		accumulatedTorque = 0.0;
	}
	
	public void applyForce(Vec2 force) {
		accumulatedForce.iadd(force);
	}
	
	public void applyForce(Vec2 force, Vec2 offset) {
		accumulatedForce.iadd(force);
		accumulatedTorque += Vec2.cross(offset.sub(state.x), force);
	}
	
	public State getState() {
		return state;
	}

	public void setState(State state) {
		this.state = state;
	}

	public double getMass() {
		return mass;
	}

	public void setMass(double mass) {
		this.mass = mass;
	}

	public double getInertia() {
		return inertia;
	}

	public void setInertia(double inertia) {
		this.inertia = inertia;
	}
	
	public Vec2 getPosition() {
		return state.x;
	}
	
	public void setPosition(Vec2 position) {
		state.x = position;
	}
	
	public Vec2 getVelocity() {
		return state.v;
	}
	
	public void setVelocity(Vec2 velocity) {
		state.v = velocity;
	}
	
	public double getOrientation() {
		return state.a;
	}
	
	public void setOrientation(double orientation) {
		state.a = orientation;
	}
	
	public double getAngularSpeed() {
		return state.w;
	}
	
	public void setAngularSpeed(double angularSpeed) {
		state.w = angularSpeed;
	}
}
